package com.woniu.order.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.exception.account.AccountException;
import com.woniu.exception.order.OrderException;
import com.woniu.exception.order.OrderExceptionCode;
import com.woniu.model.Result;
import com.woniu.order.client.FlowClient;
import com.woniu.order.client.UserClient;
import com.woniu.order.cliententity.entity.FlowHandle;
import com.woniu.order.cliententity.entity.TUser;
import com.woniu.order.cliententity.form.AddHandelForm;
import com.woniu.order.dto.DownpaymentDto;
import com.woniu.order.mapper.TDownpaymentMapper;
import com.woniu.order.mapper.TOrderMapper;
import com.woniu.order.model.TDownpayment;
import com.woniu.order.model.TOrder;
import com.woniu.order.param.PagePayParam;
import com.woniu.order.service.TDownpaymentService;
import com.woniu.order.util.AlipayUtil;
import com.woniu.order.util.config.AlipayConfiguration;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年06月03日
 */
@Service
public class TDownpaymentServiceImpl extends ServiceImpl<TDownpaymentMapper, TDownpayment> implements TDownpaymentService {

    @Resource
    private AlipayUtil alipayUtil;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private AlipayConfiguration alipayConfiguration;
    @Resource
    private UserClient userClient;
    @Resource
    private TDownpaymentMapper downpaymentMapper;
    @Resource
    private TOrderMapper orderMapper;
    @Resource
    private AlipayClient alipayClient;

    @Resource
    private FlowClient flowClient;

    /**
     * 判断用户信誉分，发起定金支付
     * @return
     */
    @Override
    public DownpaymentDto payDownpayment(Integer userId) throws Exception {

        Result<TUser> tUserResult = userClient.userById(userId.longValue());
        if (tUserResult.getCode() != 200) {
            throw new AccountException(tUserResult.getCode(), tUserResult.getMessage());
        }
        Double money = null;
        if (tUserResult.getData().getCredibility() > 60) {
            return null;
        } else  {
            money = 20.00;
        }
        //生成押金表数据
        String orderNum = new Snowflake(1, 1).nextIdStr();//押金订单编号
        String downpaymentNum = new Snowflake(1, 2).nextIdStr();//押金订单编号
        System.out.println(orderNum);
        System.out.println(downpaymentNum);
        TDownpayment downpayment = new TDownpayment(null, downpaymentNum, orderNum, userId.longValue(), null, 0, LocalDateTime.now(),money);
        downpaymentMapper.insert(downpayment);
        //组装需要的参数
        PagePayParam payParam = new PagePayParam();
        payParam.setBody("再生道押金支付");
        payParam.setMoney(money);
        payParam.setNotifyUrl("http://kggd7k.natappfree.cc/order/tDownpayment/notify");//异步回调
        payParam.setReturnUrl("http://localhost:8081/#/Order");//同步回调（客户端）
        payParam.setOrderId(downpayment.getDownpaymentNum());
        payParam.setSubject("再生道");
        TOrder tOrder = new TOrder();
        tOrder.setId(orderNum);
        orderMapper.insert(tOrder);

        rabbitTemplate.convertAndSend("order_num_delay_queue",downpaymentNum);
        //调用接口
        String form = alipayUtil.pagePay(payParam);
        DownpaymentDto downpaymentDto = new DownpaymentDto();
        downpaymentDto.setPayForm(form);
        downpaymentDto.setDownpayment(downpayment);
        return downpaymentDto;
    }
    /**
     * 支付押金的异步回调
     * @return 返回"SUCCESS"
     */
    @Override
    public String payNotify(Map<String, String> params) throws AlipayApiException {
        System.out.println("异步回调");
        //验签
        //在异步回调业务层验签 防止伪造请求
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayUtil.alipayPublicKey, "utf-8", "RSA2"); //调用SDK验证签名
        if (signVerified) {
            //验签通过
            //取出订单编号,修改状态
            String tradeStatus = params.get("trade_status");
            if (tradeStatus.equals("TRADE_SUCCESS")) {
                //支付成功
                //修改订单状态为已支付
                String orderNum = params.get("out_trade_no");
                QueryWrapper<TDownpayment> wrapper = new QueryWrapper<>();
                wrapper.eq("downpayment_num", orderNum);
                TDownpayment tDownpayment = downpaymentMapper.selectOne(wrapper);

                //判断订单是否是未支付
                if (tDownpayment.getPayState() == 0) {
                    System.out.println(params);
                    //获取支付时间
                    String payTimeStr = params.get("gmt_payment");
                    System.out.println(payTimeStr);
                    //修改支付时间
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    LocalDateTime parse = LocalDateTime.parse(payTimeStr, formatter);
                    tDownpayment.setPayState(1);
                    tDownpayment.setPayTime(LocalDateTime.from(parse));
                    downpaymentMapper.updateById(tDownpayment);


                    //新增流程执行
                    AddHandelForm addHandelForm = new AddHandelForm(1, 1, null, tDownpayment.getOrderNum(), null);
                    Result<FlowHandle> add = flowClient.add(addHandelForm);
                    System.out.println(JSONUtil.toJsonStr(add));
                    if (add.getCode()!=200){
                        throw new OrderException(add.getCode(),add.getMessage());
                    }
                }
                return tDownpayment.getOrderNum();


            }
        }

    return null;
    }
    /**
     * 退押金
     * @param orderNum 订单编号
     * @return 返回阿里响应结果
     * @throws Exception
     */
    @Override
    public String refund(String orderNum, int userId) throws AlipayApiException {
        QueryWrapper<TDownpayment> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",orderNum);
        TDownpayment tDownpayment = downpaymentMapper.selectOne(wrapper);
        System.out.println(tDownpayment);
        System.out.println(userId);
        if (tDownpayment.getUserId()!=userId){
            throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_NO_ORDER);
        }

        String reason="退押金";
        //设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ orderNum +"\","
                + "\"refund_amount\":\""+ tDownpayment.getPrice() +"\","
                + "\"refund_reason\":\""+ reason +"\","
                + "\"out_request_no\":\""+ UUID.randomUUID().toString() +"\"}");
        String result = alipayClient.execute(alipayRequest).getBody();

        if (tDownpayment.getPayState()==1){
            tDownpayment.setPayState(2);
        }
        downpaymentMapper.updateById(tDownpayment);

        return result;
    }

}
